home *** CD-ROM | disk | FTP | other *** search
- /* xlsym - symbol handling routines */
- /* Copyright (c) 1985, by David Michael Betz
- All Rights Reserved
- Permission is granted for unrestricted non-commercial use */
-
- #include "xlisp.h"
-
- /* external variables */
- extern NODE *oblist,*keylist;
- extern NODE *s_unbound;
- extern NODE *xlstack;
- extern NODE *xlenv;
-
- /* forward declarations */
- FORWARD NODE *symenter();
- FORWARD NODE *findprop();
-
- /* xlenter - enter a symbol into the oblist or keylist */
- NODE *xlenter(name,type)
- char *name;
- {
- return (symenter(name,type,(*name == ':' ? keylist : oblist)));
- }
-
- /* symenter - enter a symbol into a package */
- LOCAL NODE *symenter(name,type,listsym)
- char *name; int type; NODE *listsym;
- {
- NODE *oldstk,*lsym,*nsym,newsym;
- int cmp;
-
- /* check for nil */
- if (strcmp(name,"NIL") == 0)
- return (NIL);
-
- /* check for symbol already in table */
- lsym = NIL;
- nsym = getvalue(listsym);
- while (nsym) {
- if ((cmp = strcmp(name,xlsymname(car(nsym)))) <= 0)
- break;
- lsym = nsym;
- nsym = cdr(nsym);
- }
-
- /* check to see if we found it */
- if (nsym && cmp == 0)
- return (car(nsym));
-
- /* make a new symbol node and link it into the list */
- oldstk = xlsave(&newsym,NULL);
- newsym.n_ptr = newnode(LIST);
- rplaca(newsym.n_ptr,xlmakesym(name,type));
- rplacd(newsym.n_ptr,nsym);
- if (lsym)
- rplacd(lsym,newsym.n_ptr);
- else
- setvalue(listsym,newsym.n_ptr);
- xlstack = oldstk;
-
- /* return the new symbol */
- return (car(newsym.n_ptr));
- }
-
- /* xlsenter - enter a symbol with a static print name */
- NODE *xlsenter(name)
- char *name;
- {
- return (xlenter(name,STATIC));
- }
-
- /* xlmakesym - make a new symbol node */
- NODE *xlmakesym(name,type)
- char *name;
- {
- NODE *oldstk,sym,*str;
-
- /* create a new stack frame */
- oldstk = xlsave(&sym,NULL);
-
- /* make a new symbol node */
- sym.n_ptr = newnode(SYM);
- setvalue(sym.n_ptr,*name == ':' ? sym.n_ptr : s_unbound);
- sym.n_ptr->n_symplist = newnode(LIST);
- rplaca(sym.n_ptr->n_symplist,str = newnode(STR));
- str->n_str = (type == DYNAMIC ? strsave(name) : name);
- str->n_strtype = type;
-
- /* restore the previous stack frame */
- xlstack = oldstk;
-
- /* return the new symbol node */
- return (sym.n_ptr);
- }
-
- /* xlsymname - return the print name of a symbol */
- char *xlsymname(sym)
- NODE *sym;
- {
- return (car(sym->n_symplist)->n_str);
- }
-
- /* xlframe - create a new environment frame */
- NODE *xlframe(env)
- NODE *env;
- {
- NODE *ptr;
- ptr = newnode(LIST);
- rplacd(ptr,env);
- return (ptr);
- }
-
- /* xlbind - bind a value to a symbol */
- xlbind(sym,val,env)
- NODE *sym,*val,*env;
- {
- NODE *ptr;
-
- /* create a new environment list entry */
- ptr = newnode(LIST);
- rplacd(ptr,car(env));
- rplaca(env,ptr);
-
- /* create a new variable binding */
- rplaca(ptr,newnode(LIST));
- rplaca(car(ptr),sym);
- rplacd(car(ptr),val);
- }
-
- /* xlgetvalue - get the value of a symbol (checked) */
- NODE *xlgetvalue(sym)
- NODE *sym;
- {
- NODE *val;
- while ((val = xlxgetvalue(sym)) == s_unbound)
- xlunbound(sym);
- return (val);
- }
-
- /* xlxgetvalue - get the value of a symbol */
- NODE *xlxgetvalue(sym)
- NODE *sym;
- {
- NODE *val;
-
- /* check for this being an instance variable */
- if (xlobgetvalue(sym,&val))
- return (val);
-
- /* get the value from the environment list or the global value */
- return (xlygetvalue(sym));
- }
-
- /* xlygetvalue - get the value of a symbol (no instance variables) */
- NODE *xlygetvalue(sym)
- NODE *sym;
- {
- NODE *fp,*ep;
-
- /* check the environment list */
- for (fp = xlenv; fp; fp = cdr(fp))
- for (ep = car(fp); ep; ep = cdr(ep))
- if (sym == car(car(ep)))
- return (cdr(car(ep)));
-
- /* return the global value */
- return (getvalue(sym));
- }
-
- /* xlsetvalue - set the value of a symbol */
- xlsetvalue(sym,val)
- NODE *sym,*val;
- {
- NODE *fp,*ep;
-
- /* check for this being an instance variable */
- if (xlobsetvalue(sym,val))
- return;
-
- /* look for the symbol in the environment list */
- for (fp = xlenv; fp; fp = cdr(fp))
- for (ep = car(fp); ep; ep = cdr(ep))
- if (sym == car(car(ep))) {
- rplacd(car(ep),val);
- return;
- }
-
- /* store the global value */
- setvalue(sym,val);
- }
-
- /* xlgetprop - get the value of a property */
- NODE *xlgetprop(sym,prp)
- NODE *sym,*prp;
- {
- NODE *p;
- return ((p = findprop(sym,prp)) ? car(p) : NIL);
- }
-
- /* xlputprop - put a property value onto the property list */
- xlputprop(sym,val,prp)
- NODE *sym,*val,*prp;
- {
- NODE *oldstk,p,*pair;
- if ((pair = findprop(sym,prp)) == NIL) {
- oldstk = xlsave(&p,NULL);
- p.n_ptr = newnode(LIST);
- rplaca(p.n_ptr,prp);
- rplacd(p.n_ptr,pair = newnode(LIST));
- rplaca(pair,val);
- rplacd(pair,cdr(sym->n_symplist));
- rplacd(sym->n_symplist,p.n_ptr);
- xlstack = oldstk;
- }
- rplaca(pair,val);
- }
-
- /* xlremprop - remove a property from a property list */
- xlremprop(sym,prp)
- NODE *sym,*prp;
- {
- NODE *last,*p;
- last = NIL;
- for (p = cdr(sym->n_symplist); consp(p) && consp(cdr(p)); p = cdr(last)) {
- if (car(p) == prp)
- if (last)
- rplacd(last,cdr(cdr(p)));
- else
- rplacd(sym->n_symplist,cdr(cdr(p)));
- last = cdr(p);
- }
- }
-
- /* findprop - find a property pair */
- LOCAL NODE *findprop(sym,prp)
- NODE *sym,*prp;
- {
- NODE *p;
- for (p = cdr(sym->n_symplist); consp(p) && consp(cdr(p)); p = cdr(cdr(p)))
- if (car(p) == prp)
- return (cdr(p));
- return (NIL);
- }
-
- /* xlsinit - symbol initialization routine */
- xlsinit()
- {
- /* initialize the oblist */
- oblist = xlmakesym("*OBLIST*",STATIC);
- setvalue(oblist,newnode(LIST));
- rplaca(getvalue(oblist),oblist);
-
- /* initialize the keyword list */
- keylist = xlsenter("*KEYLIST*");
-
- /* enter the unbound symbol indicator */
- s_unbound = xlsenter("*UNBOUND*");
- setvalue(s_unbound,s_unbound);
- }